﻿using BCCommon;
using BCEntity.Common.SystemExceptionRecord;
using Dapper;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Data;
using System.Threading.Tasks;

namespace BCData.Common.SystemExceptionRecord
{
    public class SystemExceptionRecordData : ISystemExceptionRecordData
    {
        private readonly IConfiguration configuration;
        private readonly ISqlCommand sqlCommand;

        private const string QUERY_EXISTS = @"SELECT 1 FROM systemexceptionrecord";
        private const string QUERY = @"SELECT Id,CreateTime,OccurrenceCount,Name,HelpLink,Source,Message,StackTrace,HResult,Data,InnerException FROM systemexceptionrecord";
        
        public SystemExceptionRecordData(IConfiguration configuration)
        {
            this.configuration = configuration;
            this.sqlCommand = new SqlCommand(configuration["MySqlConnectionString"]);
        }

        public async void Create(SystemExceptionRecordEntity entity)
        {
            string getSql = @"SELECT Id FROM SystemExceptionRecord WHERE Name=?Name AND HelpLink=?HelpLink AND Source=?Source AND Message=?Message AND StackTrace=?StackTrace LIMIT 1";
            DynamicParameters getParameters = new DynamicParameters();
            getParameters.Add("?Name", entity.Name, DbType.AnsiString);
            getParameters.Add("?HelpLink", entity.HelpLink, DbType.AnsiString);
            getParameters.Add("?Source", entity.Source, DbType.AnsiString);
            getParameters.Add("?Message", entity.Message, DbType.String);
            getParameters.Add("?StackTrace", entity.StackTrace, DbType.String);
            var getResult = await sqlCommand.ExecuteScalarAsync<long>(getSql,CommandType.Text, getParameters);

            if (getResult == 0)
            {
                string sql = SqlCommands.GetInsertSql("SystemExceptionRecord", new[] { "Name", "HelpLink", "Source", "Message", "StackTrace", "HResult", "Data", "InnerException", "CreateTime" });

                DynamicParameters parameters = new DynamicParameters();

                parameters.Add("?Name", entity.Name, DbType.AnsiString);
                parameters.Add("?HelpLink", entity.HelpLink, DbType.AnsiString);
                parameters.Add("?Source", entity.Source, DbType.AnsiString);
                parameters.Add("?Message", entity.Message, DbType.String);
                parameters.Add("?StackTrace", entity.StackTrace, DbType.String);
                parameters.Add("?HResult", entity.HResult, DbType.Int32);
                parameters.Add("?Data", entity.Data, DbType.String);
                parameters.Add("?InnerException", entity.InnerException, DbType.String);
                parameters.Add("?CreateTime", entity.CreateTime, DbType.DateTime);

                await sqlCommand.ExecuteAsync(sql, CommandType.Text, parameters);
            }
            else
            {
                string sql = SqlCommands.GetUpdateSql("SystemExceptionRecord", new string[] { "Data", "CreateTime" }, new string[] { "Id" });
                DynamicParameters parameters = new DynamicParameters();
                parameters.Add("?Data", entity.Data, DbType.String);
                parameters.Add("?CreateTime", entity.CreateTime, DbType.DateTime);
                parameters.Add("?Id", getResult, DbType.Int64);
                await sqlCommand.ExecuteAsync(sql, CommandType.Text, parameters);
            }

        }

        public async Task<(IEnumerable<SystemExceptionRecordEntity>,int)> GetSystemExceptionRecords(string name,DateTime? start, DateTime? end, string sortName, bool? ascending, int pageIndex, int pageSize)
        {
            List<string> wheres = new List<string>();
            DynamicParameters parameters = new DynamicParameters();
            if (!string.IsNullOrWhiteSpace(name))
            {
                wheres.Add("Name LIKE CONCAT('%',CONCAT(?Name,'%'))");
                parameters.Add("?Name", name, DbType.AnsiString);
            }
            if (start.HasValue && !end.HasValue)
            {
                wheres.Add("CreateTime>=?Start");
                parameters.Add("?Start", start.Value.Date, DbType.DateTime);
            }
            else if (!start.HasValue && end.HasValue)
            {
                wheres.Add("CreateTime<=?End");
                parameters.Add("?End", end.Value.AddDays(1).Date, DbType.DateTime);
            }
            else if (start.HasValue && end.HasValue)
            {
                wheres.Add("CreateTime>=?Start AND CreateTime<=?End");
                parameters.Add("?Start", start.Value.Date, DbType.DateTime);
                parameters.Add("?End", end.Value.AddDays(1).Date, DbType.DateTime);
            }

            string sql = string.Format("{0} {1} ORDER BY {4} {5} LIMIT {2}, {3}; SELECT COUNT(1) FROM SystemExceptionRecord {1};",
                QUERY,
                 wheres.Count > 0 ? " WHERE " + string.Join(" AND ", wheres) : "",
                (pageIndex == 0 ? 0 : pageIndex - 1) * pageSize,
                pageSize,
                string.IsNullOrWhiteSpace(sortName) ? "CreateTime" : sortName,
                ascending.HasValue && ascending.Value ? "ASC" : "DESC");

            return await sqlCommand.QueryMultipleAsync<SystemExceptionRecordEntity, int>(sql,CommandType.Text, parameters);
        }
    }
}
